图像处理20210418

88次阅读
没有评论

共计 5412 个字符,预计需要花费 14 分钟才能阅读完成。

提醒:本文最后更新于 2024-07-26 10:25,文中所关联的信息可能已发生改变,请知悉!

图片素材

图像处理 20210418

人为给出噪声

随机 100 个噪声点

代码

import cv2 as cv
import numpy as np

img = cv.imread("img.png", 1)
(rows, cols, chn) = img.shape
cv.imshow("img.png", img)

# 加噪声
for i in range(100):
    x = np.random.randint(0, rows)
    y = np.random.randint(0, cols)
    img[x, y, :] = 255

cv.imshow("noise", img)
cv.imwrite("img_noise.png", img)
cv.waitKey()
cv.destroyAllWindows()

结果

图像处理 20210418

噪声检测

代码

# python3.8
# utf-8
"""
1. 将图片缩小二分之一:(这里只给出了生成部分,没有给出检测部分)取左上角的点
2. 找出噪声点:划分方法一
    划分方法二
    处理特殊点
    标记次数
3. 标记
    将噪声点的像素值标记为 0
"""
import cv2 as cv
import numpy as np

class PixelChannel:
    def __init__(self, channel, noise, row, col):
        self.noise = noise
        self.channel = channel
        self.row = row
        self.col = col

class Part:
    def __init__(self, x, y, area):
        self.x = x
        self.y = y
        self.area = area

# 将图像缩小到一半
def half(pixel_channel):
    row = pixel_channel.row
    col = pixel_channel.col
    half_row = row // 2
    half_col = col // 2
    result = PixelChannel()
    result.row = half_row
    result.col = half_col
    for i in range(row, 2):
        for j in range(col, 2):
            result.channel[i // 2][j // 2] = pixel_channel.channel[i][j]
    return result

# 建立像素通道类
def create_pixel_channel(img_channel):
    (row, col) = img_channel.shape
    result = PixelChannel(img_channel, noise_check(img_channel), row, col)
    return result

# 不考虑位置
def division1(_8area):
    result = [0] * 8
    p1 = [_8area[0][0], _8area[0][1], _8area[0][2], _8area[1][2], _8area[2][2], _8area[2][1], _8area[2][0],
          _8area[1][0]]
    p = sorted(p1)
    q = [abs(int(p[0]) - int(p[1])), abs(int(p[1]) - int(p[2])), abs(int(p[2]) - int(p[3])), abs(int(p[3]) - int(p[4])),
         abs(int(p[4]) - int(p[5])), abs(int(p[5]) - int(p[6])), abs(int(p[6]) - int(p[7]))]
    # 判断区分度
    if max(q) < 10:
        return result, False
    max_index = q.index(max(q))
    for i in range(0, max_index + 1):
        result[p1.index(p[i])] = 1
    for i in range(8):
        if result[i] != 1:
            result[i] = 2
    """
    min_index = 0
    for i in range(1, 8):
        if p[i] < p[min_index]:
            min_index = i
    max_index1 = min_index
    for i in range(1, 8):
        if p[i] > p[max_index1]:
            max_index1 = i
    max_index2 = min_index
    for i in range(1, 8):
        if i != max_index1 and p[i] > p[max_index2]:
            max_index2 = i
    max_index3 = min_index
    for i in range(1, 8):
        if i != max_index1 and i != max_index2 and p[i] > p[max_index3]:
            max_index3 = i
    max_index4 = min_index
    for i in range(1, 8):
        if i != max_index1 and i != max_index2 and i != max_index3 and p[i] > p[max_index4]:
            max_index4 = i
    # 将较小的的四个标记为 1 区域,较大区域标记为 2
    result[max_index1] = 2
    result[max_index2] = 2
    result[max_index3] = 2
    result[max_index4] = 2
    for i in range(8):
        if result[i] != 2:
            result[i] = 1
    """
    return result, True

# 考虑位置
def division2(_8area):
    result = [0] * 8
    p = [_8area[0][0], _8area[0][1], _8area[0][2], _8area[1][2],
         _8area[2][2], _8area[2][1], _8area[2][0], _8area[1][0]]
    d = [int(p[0]) - int(p[1]), int(p[1]) - int(p[2]), int(p[2]) - int(p[3]), int(p[3]) - int(p[4]),
         int(p[4]) - int(p[5]), int(p[5]) - int(p[6]), int(p[6]) - int(p[7]), int(p[7]) - int(p[0])]
    max_index = 0
    min_index = 0
    for i in range(1, 8):
        if d[i] > d[max_index]:
            max_index = i
        if d[i] < d[min_index]:
            min_index = i
    if max_index == min_index:
        pass
    elif max_index > min_index:
        for i in range(0, min_index + 1):
            result[i] = 1
        for i in range(min_index + 1, max_index + 1):
            result[i] = 2
        if max_index < 7:
            for i in range(max_index + 1, 8):
                result[i] = 1
    elif max_index < min_index:
        for i in range(0, max_index + 1):
            result[i] = 2
        for i in range(max_index + 1, min_index + 1):
            result[i] = 1
        if min_index < 7:
            for i in range(min_index + 1, 8):
                result[i] = 2
    # 判断区分度
    max1 = 0
    for i in range(8):
        if result[i] == 1 and p[i] > max1:
            max1 = p[i]
    min2 = 0
    for i in range(8):
        if result[i] == 2 and p[i] < min2:
            min2 = p[i]
    if max1 - min2 < 10:
        return result, False
    else:
        return result, True

# 一维数组映射到二维
def _1d_2_2d(x):
    if x == 0:
        return 0, 0
    elif x == 1:
        return 0, 1
    elif x == 2:
        return 0, 2
    elif x == 3:
        return 1, 2
    elif x == 4:
        return 2, 2
    elif x == 5:
        return 2, 1
    elif x == 6:
        return 2, 0
    elif x == 7:
        return 1, 0

# 特殊值处理
def special_check(_8area):
    p = [_8area[0][0], _8area[0][1], _8area[0][2], _8area[1][2],
         _8area[2][2], _8area[2][1], _8area[2][0], _8area[1][0]]
    p_sum = int(p[0])+int(p[1])+int(p[2])+int(p[3])+int(p[4])+int(p[5])+int(p[6])+int(p[7])
    max_differ = 0
    max_index = 0
    for i in range(8):
        if abs(int(p[i]) - (p_sum - int(p[i])) // 7) > max_differ:
            max_differ = abs(int(p[i]) - (p_sum - int(p[i])) // 7)
            max_index = i
    if max_differ > 10:
        return _1d_2_2d(max_index)
    else:
        return -1, -1

def noise_check(img_channel):
    (row, col) = img_channel.shape
    result = [[0] * col for i in range(row)]
    for i in range(1, row - 1):
        for j in range(1, col - 1):
            # _8_area = type(img_channel)
            _8_area = [[0] * 3 for i in range(3)]
            _8_area[0][0] = img_channel[i - 1][j - 1]
            _8_area[0][1] = img_channel[i - 1][j]
            _8_area[0][2] = img_channel[i - 1][j + 1]
            _8_area[1][2] = img_channel[i][j + 1]
            _8_area[2][2] = img_channel[i + 1][j + 1]
            _8_area[2][1] = img_channel[i + 1][j]
            _8_area[2][0] = img_channel[i + 1][j - 1]
            _8_area[1][0] = img_channel[i][j - 1]
            # 不考虑位置
            part1, flag1 = division1(_8_area)
            # 考虑位置
            part2, flag2 = division2(_8_area)
            if flag1 == False or flag2 == False:
                continue
            # 处理特殊值
            sx, sy = special_check(_8_area)
            if sx != -1:
                result[i - 1 + sx][j - 1 + sy] += 1
            # 比较
            for k in range(8):
                if part1[k] != part2[k]:
                    x, y = _1d_2_2d(k)
                    result[i - 1 + x][j - 1 + y] += 1
    return result

def mark(pixel_channel):
    for i in range(pixel_channel.row):
        for j in range(pixel_channel.col):
            if pixel_channel.noise[i][j] >= 6:
                pixel_channel.channel[i][j] = 0
    return pixel_channel

def main():
    # 图像地址
    img_address = "img_noise.png"
    # 以 BGR 方式读入图像
    img = cv.imread(img_address, 1)
    cv.imshow("img_noise.png", img)
    # 通道分离
    channel_b, channel_g, channel_r = cv.split(img)
    # 建立像素通道类
    b = create_pixel_channel(channel_b)
    g = create_pixel_channel(channel_g)
    r = create_pixel_channel(channel_r)

    fp = open('b.noise.csv', 'w')
    for i in range(b.row):
        for j in range(b.col):
            print(b.noise[i][j], file=fp, end='')
            print(",", file=fp, end='')
        print("", file=fp)

    fp = open('b.pixel.csv', 'w')
    for i in range(b.row):
        for j in range(b.col):
            print(b.channel[i][j], file=fp, end='')
            print(",", file=fp, end='')
        print("", file=fp)

    new_img = cv.merge((mark(b).channel, mark(g).channel, mark(r).channel))
    cv.imwrite("denoised_img.png", new_img)
    cv.imshow("denoised_img.png", new_img)
    cv.waitKey()
    cv.destroyAllWindows()

if __name__ == '__main__':
    main()

结果

图像处理 20210418

如下图所示,红框内表示没有被标记出的噪声点

图像处理 20210418

正文完
 0
icvuln
版权声明:本站原创文章,由 icvuln 于2021-04-18发表,共计5412字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)